import httplib
import base64
import StringIO
import threading
import time
import wx

import serial

class Trendnet():
    
    def __init__(self, ip='1.1.1.1', username='admin', password='admin'):
        self.IP = ip
        self.Username = username
        self.Password = password
        self.Connected = False

    def Connect(self):
        if self.Connected == False:
            try:
                print 'Atempting to connect to camera', self.IP, self.Username, self.Password
                h = httplib.HTTP(self.IP)
                h.putrequest('GET','/cgi/mjpg/mjpeg.cgi')
                h.putheader('Authorization', 'Basic %s' % base64.encodestring('%s:%s' % (self.Username, self.Password))[:-1])
                h.endheaders()
                errcode, errmsg, headers = h.getreply()
                self.File = h.getfile()
                print 'Connected!'
                self.Connected = True
            except:
                print 'Unable to connect!'
                self.Connected = False
            
    def Disconnect(self):
        self.Connected = False
        print 'Camera Disconnected!'

    def Update(self):
        if self.Connected: 
            s = self.File.readline()        # '--myboundry'
            s = self.File.readline()        # 'Content-Length: #####'
            framesize = int(s[16:])
            s = self.File.read(framesize)    # jpeg data
            while s[0] != chr(0xff):
                s = s[1:]
            return StringIO.StringIO(s)
            
class CameraPanel(wx.Panel):
    
    def __init__(self, parent, camera):
        wx.Panel.__init__(self, parent, id=wx.ID_ANY, style=wx.SIMPLE_BORDER)
        self.Camera = camera
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
        
        self.AButton = wx.Button(self, label="Unused button",pos=(750,460))
        self.Bind(wx.EVT_BUTTON,self.Button1,self.AButton)
        
        self.leftcolor  = wx.BLUE_BRUSH
        self.rightcolor = wx.BLUE_BRUSH
    
    def OnEraseBackground(self, event):
        pass
    
    def OnPaint(self, event):
        dc = wx.BufferedPaintDC(self)
        
        if self.Camera.Connected == True:
            try:
                stream = self.Camera.Update()
                if stream != None:
                    img = wx.ImageFromStream(stream)
                    bmp = wx.BitmapFromImage(img)
                    dc.DrawBitmap(bmp, 100, 0, True)
                    
                    dc.SetBrush(self.leftcolor)
                    dc.DrawRectangle(80, 40, 20, 400)
                    dc.SetBrush(self.rightcolor)
                    dc.DrawRectangle(740, 40, 20, 400)
            except:
                pass
        else:
            dc.SetBrush(wx.WHITE_BRUSH)
            dc.DrawRectangle(-1, -1, 620, 480)
            
        dc.DrawCircle(340+100, 270, 5)
        dc.DrawCircle(280+100, 270, 5)
        
    def Button1(self, event):
        pass

if __name__ == '__main__':
    
    # xBee serial port settings
    myPort = 16 #17 #~ note: use port number - 1
    myBaud = 38400
    
    # Arbotix Commander serial port settings
    myPort2 = 2 #3 #~ note: use port number - 1
    myBaud2 = 38400
    
    def CamThread():
        byte_string = ""
        while True:
            # update camera
            campanel.Refresh()

            # If xbee serial port was opened and is open.
            if serExist and ser.isOpen():
                # read all bytes in the buffer
                while ser.inWaiting():
                    byte = ser.read()
                    # if the end of packet symbol is seen...
                    if byte == ')':
                        side = byte_string.split()[0][0]
                        num = byte_string.split()[0][2:]
                        try:
                            int(num)
                          #  print num, side
                            if side == 'R':
                                if int(num) < 21:
                                    campanel.rightcolor = wx.RED_BRUSH
                                elif int(num) < 26:
                                    campanel.rightcolor = wx.Brush(wx.Color(255,153,51))
                                elif int(num) < 35:
                                    campanel.rightcolor = wx.Brush(wx.Color(255,255,51))
                                else:
                                    campanel.rightcolor = wx.GREEN_BRUSH
                            elif side =='L':
                                if int(num) < 19:
                                    campanel.leftcolor = wx.RED_BRUSH
                                elif int(num) < 26:
                                    campanel.leftcolor = wx.Brush(wx.Color(255,153,51))
                                elif int(num) < 35:
                                    campanel.leftcolor = wx.Brush(wx.Color(255,255,51))
                                else:
                                    campanel.leftcolor = wx.GREEN_BRUSH
                        except ValueError, error:
                            print error
                        finally:
                            byte_string = ""
                            break
                    else:
                        byte_string = byte_string + byte
                        
                if arbcomserExist and arbcomser.isOpen():    
                    while arbcomser.inWaiting():
                        # forwarding bytes
                        byte = arbcomser.read()
                        ser.write(byte)
            #time.sleep(.01) #~ this delay no longer seems necessary
            
            
    app = wx.App(0)
    
    # Opening the serial port for the xBee
    try:
        ser = serial.Serial(myPort,myBaud) #port number - 1
        print "Successfully connected to port {0} at {1} baud".format(myPort,myBaud)
        serExist = 1
    
    except serial.SerialException:
        print "Couldn't open xBee serial port. Try again later."
        serExist = 0
    
    # Opening the serial port for the Arbotix Commander
    try:
        arbcomser = serial.Serial(myPort2,myBaud2) #port number - 1
        print "Successfully connected to port {0} at {1} baud".format(myPort2,myBaud2)
        arbcomserExist = 1
    
    except serial.SerialException:
        print "Couldn't open Arbotix Commander serial port. Try again later."
        arbcomserExist = 0
    
    # Magic GUI/Camera stuff
    wx.Log_SetActiveTarget(wx.LogStderr())
    
    frame = wx.Frame(parent=None, id=wx.ID_ANY, title='UpCam.py', size=(500,500),style=wx.DEFAULT_FRAME_STYLE & ~wx.RESIZE_BORDER)
    camera = Trendnet('192.168.0.70')
    camera.Connect()
    campanel = CameraPanel(frame, camera)
    campanel.SetSize((820,480))
    
    sizer = wx.BoxSizer(wx.VERTICAL)
    sizer.Add(campanel, 1, wx.EXPAND|wx.ALL, 5)
    frame.SetSizer(sizer)
    frame.Fit()
    frame.Show(True)
    # sizer.RecalcSizes() #doesn't work.
    
    thread = threading.Thread(target=CamThread)
    thread.start()
    
    app.MainLoop()
    
    
